package labb2.del2;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

/**
 * @author Mikko Puustinen
 * @version 0.1, 2007-sep-26
 */
public class CollectionOfBooks {
    private ArrayList<Book> books;
    private String filename;

    /**
     * Create a standard CollectionOfBooks loading the contents from books.dat.
     */
    public CollectionOfBooks() {
        this("books.dat");
    }

    /**
     * Creates a CollectionOfBooks.
     * <p/>
     * Tries to get a file at location specified in path.
     *
     * @param path location of the saved collection.
     */
    @SuppressWarnings("unchecked")
    public CollectionOfBooks(String path) {
        FileInputStream fis;
        ObjectInputStream ois = null;
        filename = path;


        try {
            fis = new FileInputStream(filename);
            ois = new ObjectInputStream(fis);
            books = (ArrayList<Book>) ois.readObject();
        }
        catch (Exception e) {
            System.out.println("File error. Generating empty collection.");
            books = new ArrayList<Book>();
        }
        finally {
            try {
                if (ois != null) {
                    ois.close();
                }
            }
            catch (IOException e) {
                System.out.println(e);
            }
        }
    }

    /**
     * Save file to same place as the loaded.
     *
     * @return -1 if error.
     */
    public int saveToFile() {
        return saveToFile(filename);
    }

    /**
     * Save file to a user specified location.
     *
     * @param path location of the file.
     *
     * @return -1 if error.
     */
    public int saveToFile(String path) {
        int error = 0;

        FileOutputStream fos;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(path);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(books);
        }
        catch (IOException e) {
            System.out.println(e);
            error = -1;
        }
        finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            }
            catch (IOException e) {
                System.err.println(e);
                error = -1;
            }
        }

        return error;
    }

    /**
     * Adds a book
     *
     * @param authors authors as a String array
     * @param edition edition
     * @param isbn    isbn
     * @param price   price
     * @param title   title
     */
    public void addBook(String title, String[] authors, String isbn, int edition, double price) {
        books.add(new Book(title, isbn, edition, price, authors));
    }

    /**
     * Returns all Books in the collection.
     *
     * @return all Books.
     */
    public ArrayList<Book> getAllBooks() {
        ArrayList<Book> clone = new ArrayList<Book>();
        clone.addAll(books);
        return clone;
    }

    /**
     * Gets all the Books with matching title.
     *
     * @param title the title.
     *
     * @return all matching Books.
     */
    public ArrayList<Book> getBooksByTitle(String title) {
        ArrayList<Book> ar = new ArrayList<Book>();
        for (Book b : books) {
            if (b.getTitle().matches("(?i).*" + title + ".*")) {
                ar.add(b);
            }
        }
        Collections.sort(ar);
        return ar;
    }

    /**
     * Gets all the Books with matching ISBN.
     *
     * @param isbn the ISBN.
     *
     * @return all matching Books.
     */
    public ArrayList<Book> getBooksByISBN(String isbn) {
        ArrayList<Book> ar = new ArrayList<Book>();
        for (Book b : books) {
            if (b.getISBN().matches("(?i).*" + isbn + ".*"))
                ar.add(b);
        }
        Collections.sort(ar);
        return ar;
    }

    /**
     * Gets all the Books with matching title.
     *
     * @param author the name of the Author.
     *
     * @return all matching Books.
     */
    public ArrayList<Book> getBooksByAuthor(String author) {
        ArrayList<Book> ar = new ArrayList<Book>();
        for (Book b : books) {
            for (Author a : b.getAuthors())
                if (a.getName().matches("(?i).*" + author + ".*")) {
                    ar.add(b);
                    break;
                }
        }
        Collections.sort(ar);
        return ar;
    }
}
